package com.zyl.blog.common.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Objects;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog
 * @Package: com.zyl.common.handler
 * @ClassName: MyBatisPlusFillingHandler
 * @Description: MyBatis-Plus 自动填充处理器（带配置校验和时区支持）
 * @Author FinalFantasy
 * @Date 2025/2/14-15:47
 */
@Configuration
@ConfigurationProperties(prefix = "auto-fill")
public class MyBatisPlusFillingHandler implements MetaObjectHandler {

    // 从配置文件中绑定字段名（带默认值）
    private String createTimeField = "createTime";
    private String updateTimeField = "updateTime";
    private String createdAtField = "createdAt";
    private String updatedAtField = "updatedAt";
    private String uploadTimeField = "uploadTime";
    private ZoneId timezone = ZoneId.systemDefault();

    // Setter方法用于配置绑定
    public void setCreateTimeField(String createTimeField) {
        this.createTimeField = Objects.requireNonNull(createTimeField, "createTimeField 不能为null");
    }

    public void setUpdateTimeField(String updateTimeField) {
        this.updateTimeField = Objects.requireNonNull(updateTimeField, "updateTimeField 不能为null");
    }

    public void setCreateAtField(String createAtField) {
        this.createdAtField = Objects.requireNonNull(createAtField, "createdAtField 不能为null");
    }

    public void setUpdateAtField(String updateAtField) {
        this.updatedAtField = Objects.requireNonNull(updateAtField, "updatedAtField 不能为null");
    }

    public void setUploadTimeField(String uploadTimeField) {
        this.uploadTimeField = Objects.requireNonNull(uploadTimeField, "uploadTimeField 不能为null");
    }

    public void setTimezone(String timezone) {
        try {
            this.timezone = ZoneId.of(timezone);
        } catch (DateTimeException e) {
            throw new IllegalArgumentException("无效时区配置: " + timezone);
        }
    }

    /**
     * 插入时填充字段
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now(timezone);

        // 独立检查并填充创建时间字段
        if (metaObject.hasSetter(createTimeField)) {
            fillStrategy(metaObject, createTimeField, now);
        }
        if (metaObject.hasSetter(createdAtField)) {
            fillStrategy(metaObject, createdAtField, now);
        }
        CommonOperations(metaObject);
    }

    /**
     * 更新时填充字段
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        CommonOperations(metaObject);
    }

    private void CommonOperations(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now(timezone);

        // 独立检查并填充更新时间字段
        if (metaObject.hasSetter(updateTimeField)) {
            fillStrategy(metaObject, updateTimeField, now);
        }
        if (metaObject.hasSetter(updatedAtField)) {
            fillStrategy(metaObject, updatedAtField, now);
        }

        // 独立检查并填充上传时间字段
        if (metaObject.hasSetter(uploadTimeField)) {
            fillStrategy(metaObject, uploadTimeField, now);
        }
    }
}